Rem BasicCard Sample Source Code
Rem ------------------------------------------------------------------
Rem Copyright (C) 1997-2008 ZeitControl GmbH
Rem You have a royalty-free right to use, modify, reproduce and 
Rem distribute the Sample Application Files (and/or any modified 
Rem version) in any way you find useful, provided that you agree 
Rem that ZeitControl GmbH has no warranty, obligations or liability
Rem for any Sample Application Files.
Rem ------------------------------------------------------------------

Option Explicit

#Include COMMERR.DEF
#Include COMPONNT.DEF
#Include ECTERM.DEF
#Include MISC.DEF
#include SHA.DEF
#include TLV.DEF

Declare Function PackAsn1Sequence(Data() as String) as String
Private PublicKey$, PrivateKey$, CardPublicKey$
#Message *************************************************************************************************************************************************************************/!\ PrivateKey !!!
Private CardPrivateKey$

ResetCard : Call CheckSW1SW2()

Rem  Get the card's curve parameters
Static Curve As Integer
Call GetCurveIndex (Curve) : Call CheckSW1SW2()

Call ECpSetCurve (Curve) : Call CheckLibError()

Rem  Set up the Terminal program private and public keys
PrivateKey$ = BuildKeyForCurve(Curve, "ECTERM Test Program Private Key")
Call ECpMakePublicKey(PrivateKey$, PublicKey$)
Call CheckLibError()

Rem  Read the card's public key

Call GetPublicKey (CardPublicKey$)
#Message *************************************************************************************************************************************************************************/!\ PrivateKey !!!
Call GetPrivateKey (CardPrivateKey$)

If SW1SW2 <> swCommandOK AND SW1<>sw1LeWarning Then
  Print "You must run ECINIT to initialise this card."
  Exit
End If

Call CheckSW1SW2()

Private I : For I = 1 To 10
  Print "DSA"

  Rem  Time the card while it signs a message
  Private StartTime As DateTime, EndTime As DateTime, Interval As Long

  Private Message$ : Message$ = Sha256Hash("Hello")
  Private S$ : S$ = Message$
  Print "Hash('Hello') = " + Message$ 
  Print "Signature " + Str$(I) + ":"
  Call GetDateTime (StartTime)
  Call SignDSA (S$)
  Print "Signature : " + S$
  Call GetDateTime (EndTime)
  Call CheckSW1SW2()

  Interval = TimeInterval (StartTime, EndTime)

  Rem  Verify the signature
  Private SignatureOK
  SignatureOK = ECpVerifyDSA (Message$, CardPublicKey$, S$)
  Call CheckLibError()
  If SignatureOK Then
    Print 0.001 * Interval ; : Print "seconds"
  Else
    Rem  In this program, this should only happen if the card has a
    Rem  different Elliptic Curve
    Print "Signature invalid!"
    Exit
  End If

Next I

'XXX
Print "Card Public key: "
Print CardPublicKey$
Call ECpPackPublicKey(CardPublicKey$)
Print "Card Public key: (packed) "
Print CardPublicKey$

Call ECpUnpackPublicKey(CardPublicKey$)
Print "Card Public key: (unpacked) "
Print CardPublicKey$

Print "Card Private key: "
Print CardPrivateKey$

Rem  Test failure case for DSA algorithm
Private Signature$, Hash$
Private SigData(1 to 3) as String
Private Asn1SignaturePublicKeyHash$ as String

Hash$ = Sha256Hash("Hallo")
Call ECpSignDSA (Hash$, PrivateKey$, Signature$)
If Not ECpVerifyDSA (Hash$, PublicKey$, Signature$) Then_
  Print "Internal error" : Exit
Hash$(3) = Chr$(255 - Asc(Hash$(3)))

SigData(1)=Signature$
SigData(2)=PublicKey$
SigData(3)=Hash$
Asn1SignaturePublicKeyHash$=PackAsn1Sequence(SigData)
Print "Verify invalid DSA signature:" ;
Call GetDateTime (StartTime)
Call ECVerifyDSA (Asn1SignaturePublicKeyHash$)
Call GetDateTime (EndTime)

If SW1SW2 <> swVerifyFail Then
  Print "Verify should have failed"
  Exit
End If

Interval = TimeInterval (StartTime, EndTime)
Print 0.001 * Interval ; : Print "seconds"

Function PackAsn1Sequence(Data() as String) as String
  Private Sequence$
  Private i
  Sequence$=""
  For i=LBound(Data) to UBound(Data)
     Sequence$=Sequence$+TlvCreateObject(2, Data(i))
  next i
  PackAsn1Sequence=TlvCreateObject(&H30, Sequence$)
End Function